package com.ilxqx.framework.security.handler;

import com.ilxqx.framework.security.exception.ExpiredValidationException;
import com.ilxqx.framework.security.exception.ValidationException;
import com.ilxqx.framework.system.util.ResponseUtils;
import com.ilxqx.framework.util.ResultUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.session.SessionAuthenticationException;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 登录失败处理器
 * @author venus
 */
@Component
@Slf4j
public class FrameworkAuthenticationFailureHandler implements AuthenticationFailureHandler {

    /**
     * Called when an authentication attempt fails.
     *
     * @param request   the request during which the authentication attempt occurred.
     * @param response  the response.
     * @param exception the exception which was thrown to reject the authentication
     */
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        int code = -1;
        log.warn("账号[{}]登录失败，失败原因[{}]", request.getParameter("username"), exception.getMessage());
        // 处理逻辑
        String message = "未知错误";
        if (exception instanceof UsernameNotFoundException || exception instanceof BadCredentialsException) {
            // 账号不存在
            message = "账号不存在或密码错误";
        } else if (exception instanceof DisabledException) {
            // 账号被停用
            message = "账号已被停用";
        } else if (exception instanceof SessionAuthenticationException) {
            // 只允许一个账号登录一次时发生，此时该账号已在别处被登录，且不能将其挤下
            message = "账号已经在别处登录，不能再登录";
        } else if (exception instanceof ValidationException) {

            if (exception.getClass().isAssignableFrom(ExpiredValidationException.class)) {
                // 过期验证异常
                code = 1;
                message = "验证已经过期，请重新验证";
            } else {
                // 验证异常
                message = "验证失败";
            }

        } else {
            // 其他错误
            log.warn("其他错误导致用户[{}]登录失败：{}", request.getParameter("username"), exception);
        }
        ResponseUtils.response(ResultUtils.failure(message), request, response);
    }

}
